import kotlinx.coroutines.*
import java.lang.Exception
import java.util.Objects

class DistributedCenter {
    val loadingPorts: MutableList<LoadingPort> = mutableListOf()
    val unloadingPorts: MutableList<UnloadingPort> = mutableListOf()
    var generatorInterval: Int = 1
    var duration: Int = 1
    fun startGame() {
        var amountOfLoadingPort: Int
        var amountOfUnloadingPort: Int
        while (true) {
            println("Enter amount of loading ports (more than 1):")
            amountOfLoadingPort = readln().toIntOrNull() ?: continue
            println("Enter amount of unloading ports (more than 2):")
            amountOfUnloadingPort = readln().toIntOrNull() ?: continue
            println("Enter duration of generating trucks (minutes):")
            duration = readln().toIntOrNull() ?: continue
            duration *= 60000
            println("Enter time interval of generating trucks (seconds):")
            generatorInterval = readln().toIntOrNull() ?: continue
            if (amountOfLoadingPort <= 1 || amountOfUnloadingPort <= 2 || duration < 1 || generatorInterval < 3) {
                println(
                    "Amount of loading ports have to be more than 1 port, and amount of unloading ports have to be more than 2 ports" +
                            "\nDuration can not be less than 1 minute\n" +
                            "Interval of generating trucks can not be less than 3 seconds!"
                )
                continue
            }
            break
        }
        repeat(amountOfLoadingPort) {
            loadingPorts.add(LoadingPort())
        }
        repeat(amountOfUnloadingPort) {
            unloadingPorts.add(UnloadingPort())
        }
        val truckGenerator: TruckGenerator = TruckGenerator()
        var truck: AbstractTruck
        var loadingTrucks: Int = 0
        var unloadingTrucks: Int = 0
        truckGenerator.generate(generatorInterval)
        runBlocking {
            withTimeout((duration).toLong()) {
                try {
                    while (true) {
                        for (i in unloadingPorts) {
                            if (!i.isWorking) {
                                truck = truckGenerator.channel.receive()
                                truck.model += " $unloadingTrucks"
                                i.unload(truck)
                                unloadingTrucks++
                            }
                        }
                        if (Store.products.size > 5) {
                            for (i in loadingPorts) {
                                if (!i.isWorking) {
                                    var newTruck: AbstractTruck = ListOfTrucks().getRandom(TruckType.Load)
                                    newTruck.model += " $loadingTrucks"
                                    i.load(newTruck)
                                    loadingTrucks++
                                }
                            }
                        }
                    }
                } catch (ex: Exception) {
                    truckGenerator.channel.close()
                    truckGenerator.scope.cancel()

                }
            }
        }
    }
}